import os
import tkinter as tk

from PIL import Image
from tkinter import messagebox,filedialog


def fill_image(original_image,output_path,gap):
    """
        将原始图片分割成九宫格，并保存到指定路径。
        同时，创建一个包含所有分割图片（带间隙）的合并图片。

        :param original_image: PIL Image 对象，要分割的原始图片。
        :param output_path: 字符串，分割图片和合并图片的保存路径。
        :param gap: 整数，分割图片之间的间隙（像素）。
    """
    # 确定分割的尺寸
    tile_width = original_image.width // 3
    tile_height = original_image.height // 3

    # 创建一个白色背景图，大小足以容纳9个带间隙的分割图片
    # 假设每个分割图片之间有10个像素的间隙

    background_width = 3 * (tile_width + gap) - gap
    background_height = 3 * (tile_height + gap) - gap
    # 创建一个白色背景图像
    background_image = Image.new("RGB", (background_width, background_height), "white")
    no = 1
    # 遍历3x3的网格，将分割的图片粘贴到背景图上
    for i in range(3):
        for j in range(3):
            # 计算每个分割图片的左上角坐标
            left = j * (tile_width + gap)
            top = i * (tile_height + gap)

            # 从原始图片中裁剪出分割图片
            tile_image = original_image.crop(
                (j * tile_width, i * tile_height, (j + 1) * tile_width, (i + 1) * tile_height))
            tile_image.save(f'{output_path}/{no}.png')
            no += 1
            # 将分割图片粘贴到背景图上
            background_image.paste(tile_image, (left, top))

    background_image.save(f'{output_path}/merge.png')


def open_folder(folder_path):
    """
    打开指定的文件夹。
    """
    try:
        if os.name == 'nt':  # Windows
            os.startfile(folder_path)
        else:  # macOS, Linux等
            # 对于macOS，使用'open'命令；对于Linux，可能需要根据桌面环境使用'xdg-open'或其他命令
            import subprocess
            subprocess.run(['open' if os.uname().sysname == 'Darwin' else 'xdg-open', folder_path])
    except Exception as e:
        messagebox.showerror("错误", f"无法打开文件夹：{str(e)}")


class FollowWeChatWindow(tk.Tk):
    """
    九宫格图片生成器的GUI界面。
    """
    def __init__(self):
        super().__init__()
        self.title('九宫格图片生成器')
        self.geometry('600x400')  # 设置窗口大小

        # 创建一个Frame用于包含标签、输入框和按钮
        self.frame_file = tk.Frame(self, padx=10, pady=10)
        self.frame_file.grid(row=0, column=0, padx=10, pady=10)

        self.label_tof = tk.Label(self.frame_file, text="请选择要进行转换的图片：", fg="blue")
        self.label_tof.grid(row=0, column=0, sticky=tk.W)  # 粘贴到西边（左对齐）

        self.entry_cd = tk.Entry(self.frame_file, width=40, state='disabled')
        self.entry_cd.grid(row=0, column=1, padx=5)

        self.btn_browse = tk.Button(self.frame_file, text="浏览", fg="blue", command=self.browse_file)
        self.btn_browse.grid(row=0, column=2, padx=5)

        # 间隔空隙的输入部分
        self.frame_gap = tk.Frame(self, padx=10, pady=10)
        self.frame_gap.grid(row=1, column=0, padx=10, pady=5)

        self.label_gap = tk.Label(self.frame_gap, text="请输入分割间隔空隙：", fg="blue")
        self.label_gap.grid(row=0, column=0, sticky=tk.W)

        self.entry_gap = tk.Entry(self.frame_gap, width=50)
        self.entry_gap.grid(row=0, column=1, padx=5)
        self.entry_gap.insert(0, str(10))
        # 错误信息标签
        self.label_tip = tk.Label(self, text="", fg="red", height=2, width=40)
        self.label_tip.grid(row=2, column=0, columnspan=2, pady=10, sticky=tk.W + tk.E)  # 水平居中

        # 生成九宫格图片的按钮
        self.btn_cal = tk.Button(self, text="点击生成九宫格图片", fg="white", bg="blue", command=self.ctof_clicked)
        self.btn_cal.grid(row=3, column=0, columnspan=2, pady=20, padx=20)  # 横跨两列，增加填充

        # “打开文件夹”按钮（初始时隐藏或禁用）
        self.btn_open_folder = tk.Button(self, text="打开文件夹", fg="blue", command=lambda: open_folder(None), state='disabled')
        self.btn_open_folder.grid(row=4, column=0, columnspan=2, pady=10, padx=20)  # 放置在生成按钮下方

        # 设置列的权重，以便它们根据需要扩展（这里其实不需要，因为已经指定了列宽）
        # 但为了保持代码的一致性，还是加上吧
        for i in range(3):  # 假设我们最多会有3列（实际上这里只用了2列）
            self.grid_columnconfigure(i, weight=1)

        # 额外美化：设置窗口背景色和字体
        self.configure(bg='lightgray')
        self.option_add('*Font', ('Arial', 12))  # 设置全局字体和大小


    def browse_file(self):
        """
        打开文件选择对话框，让用户选择图片文件。
        """
        file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.png;*.jpg;*.jpeg;*.bmp;*.gif")])
        if file_path:
            self.entry_cd.config(state='normal')
            self.entry_cd.delete(0, tk.END)
            self.entry_cd.insert(0, file_path)
            self.entry_cd.config(state='disabled')

    def ctof_clicked(self):
        """
        当用户点击“点击生成九宫格图片”按钮时调用的函数。
        """
        file_path = self.entry_cd.get().strip()
        gap_input = self.entry_gap.get().strip()
        if not file_path:
            self.label_tip.config(text="图片路径不能为空！")
            return

        if not os.path.isfile(file_path):
            self.label_tip.config(text="图片路径不存在，请检查！")
            return

        try:
            gap = int(gap_input)
            if gap < 0:
                raise ValueError("间隙值必须是非负整数。")
        except ValueError:
            self.label_tip.config(text="间隙值必须是非负整数！")
            return

        # 如果没有输入间隙值，则使用默认值10
        if gap == 0:
            gap = 10

        try:
            image = Image.open(file_path)
            output_path = os.path.join(os.getcwd(), 'img')  # 假设输出到当前目录下的output_nine_grid文件夹
            if not os.path.exists(output_path):
                os.makedirs(output_path)
            fill_image(image, output_path, gap)  # 调用图片分割函数
            self.label_tip.config(text="", fg="gray")  # 清空错误信息
            success_message = "九宫格图片已生成请在程序所在目录的" + output_path + "文件夹中查看！"
            self.label_tip.config(text=success_message, fg="blue")
            messagebox.showinfo("成功", "九宫格图片已成功生成！")
            # 启用“打开文件夹”按钮，并设置其命令以打开正确的文件夹
            self.btn_open_folder.config(state='normal', command=lambda: open_folder(output_path))
        except Exception as e:
            self.label_tip.config(text=f"加载图片时出错：{str(e)}")



if __name__ == "__main__":
    app = FollowWeChatWindow()
    app.mainloop()